home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1995 November
/
EnigmA AMIGA RUN 02 (1995)(G.R. Edizioni)(IT)[!][issue 1995-11][Skylink CD].iso
/
earcd
/
music
/
ptsupp_1.lha
/
PT Support archive
/
ProTrackerRep.S
< prev
next >
Wrap
Text File
|
1995-09-09
|
29KB
|
1,396 lines
;------------------------------------------------------------------------------
;
; ProTracker playroutine, revision 2C
;
; Coded by Lars "ZAP" Hamre
; Updated by Håvard "HOWARD/MENTAL DISEASES" Pedersen
;
;REVISION 2B:
;* Mastervolume. (Separate left and right for balance controls.)
;* Overstep for players using program mode.
;* Rewind/fast forward. (One pattern)
;* Easy CIA-utilising.
;* DMAWait solved. (Finally!)
;* No longer clears one word behind end of module if instrument 31 is unused.
;* F00 really halts module now. (Was ignored)
;* Slower than before. =(
;* Various small optimisations in attempt to compensate. (Bugs may appear!)
;* PT_End now stops module, even if music is still called.
;* Added (selectable) 68020+ optimisations. (Not powerful yet...) 8(
;
;REVISION 2C:
;* Overstep didn't trig on halting the module. Now does.
;* Made overstep selectable.
;* Added NoiseTracker compatibility. (Selectable through PT__NTComp) Both NTs
; vibrato and loop-position is supported. PT modules are still played as before.
;* Fixed some ucase/lcase confusion on some labels.
;* CIA-tempo wasn't reset upon PT_Init(). Now is.
;
;DMAWAIT ISSUES:
;Commodore states that atleast one rasterline must pass before rewriting to
;the audio hardware after disabling the DMA. A DMA-delay of 80 will wait
;_exactly_ one line. Still, OctaMed uses a delay equal to 64, and it sounds OK.
;Still, delays which sounds fine on your computer _may_ turn up bad on faster
;machines, so please add some extra for margins.
;
;PLEASE NOTE!
;This replay assumes exclusive access to audio hardware and OCS/ECS/AGA or
;compatible audio chips. This behaviour is _NOT_ encouraged by Commodore!
;
;------------------------------------------------------------------------------
IFND PT_MasterVol ; Mastervolume ON/OFF
PT_MasterVol = 0 ; Call PT_SetMasterVol with
ENDC ; Left in D0 and Right in D1
; ( 0 - 64 )
IFND PT__OverStep ; Signal when module is
PT__OverStep = 0 ; finished. PT_OverStep
ENDC ; contains 1 if end has reached
; and -1 if rewound past
; beginning.
IFND PT__WindFuncs ; Fast forward / Rewind
PT__WindFuncs = 0
ENDC
IFND PT__CIA ; CIA Support
PT__CIA = 0 ; Supply PT_SetIntRate with
ENDC ; rate (32-255) in D0. Do not
; trash registers.
IFND PT__DMADelay ; 80 is Commodore's
PT__DMADelay = 80 ; recommendation.
ENDC
IFND PT__68020 ; 68020+ optimisations
PT__68020 = 0
ENDC
IFND PT__NTComp ; Noisetracker compatibility
PT__NTComp = 1
ENDC
n_note equ 0 ; w
n_cmd equ 2 ; w
n_cmdlo equ 3 ; b
n_start equ 4 ; l
n_length equ 8 ; w
n_loopstart equ 10 ; l
n_replen equ 14 ; w
n_period equ 16 ; w
n_finetune equ 18 ; b
n_volume equ 19 ; b
n_dmabit equ 20 ; w
n_toneportdirec equ 22 ; b
n_toneportspeed equ 23 ; b
n_wantedperiod equ 24 ; w
n_vibratocmd equ 26 ; b
n_vibratopos equ 27 ; b
n_tremolocmd equ 28 ; b
n_tremolopos equ 29 ; b
n_wavecontrol equ 30 ; b
n_glissfunk equ 31 ; b
n_sampleoffset equ 32 ; b
n_pattpos equ 33 ; b
n_loopcount equ 34 ; b
n_funkoffset equ 35 ; b
n_wavestart equ 36 ; l
n_reallength equ 40 ; w
;------------------------------------------------------------------------------
;Macro: PT_WaitDMA()
;Purpose: Waits for the DMA-delay to expire before continuing.
;------------------------------------------------------------------------------
PT_WaitDMA macro
move.w $dff006,d1
moveq.l #PT__DMADelay-1,d0
.dmaloop1 cmp.w $dff006,d1
beq.s .dmaloop1
move.w $dff006,d1
.dmaloop2 cmp.w $dff006,d1
beq.s .dmaloop2
move.w $dff006,d1
dbf d0,.dmaloop1
endm
;------------------------------------------------------------------------------
;Function: PT_Init(Module)(A0)
;Purpose: Initializes the play-routine and restarts the module if it's
; already playing. The module may have up to 256 patterns.
;------------------------------------------------------------------------------
PT_Init move.b #0,PT_speed
move.l a0,PT_songdataptr
move.l a0,a1
lea.l 952(a1),a1
moveq.l #128-1,d0
moveq.l #0,d1
PT_loop move.l d1,d2
subq.w #1,d0
PT_loop2 move.b (a1)+,d1
cmp.b d2,d1
bgt.s PT_loop
dbra d0,PT_loop2
addq.b #1,d2
lea.l PT_samplestarts(pc),a1
lsl.l #8,d2
lsl.l #2,d2
add.l #1084,d2
add.l a0,d2
move.l d2,a2
moveq.l #31-1,d0
PT_loop3 cmp.l a2,a3
blt.s .range
clr.l (a2)
.range move.l a2,(a1)+
moveq.l #0,d1
move.w 42(a0),d1 ; sample length
beq.b .nosample
lsl.l #1,d1
add.l d1,a2
.nosample add.l #30,a0
dbra d0,PT_loop3
ifne PT__NTComp
move.b 951(a0),d1
cmp.b #$7f,d1
beq.s .NotNT ; ProTracker module
cmp.b #$78,d1
beq.w .NotNT ; Old 15-instrument converted
.WasNT move.l #6,PT_vibshift
move.b d1,PT_looppos
bra.s .GotFormat
.NotNT move.l #7,PT_vibshift
clr.b PT_looppos
.GotFormat
endc
ifne PT__CIA
moveq.l #125,d0
bsr.s PT_SetIntRate
endc
or.b #2,$bfe001
clr.b PT_counter
clr.b PT_songpos
clr.w PT_patternpos
bsr.s PT_KillSound
move.b #6,PT_speed
rts
;------------------------------------------------------------------------------
;Function: PT_End()
;Purpose: Stops the music.
;------------------------------------------------------------------------------
PT_End move.b #0,PT_speed
PT_KillSound lea.l $dff000,a0
clr.w $a8(a0)
clr.w $b8(a0)
clr.w $c8(a0)
clr.w $d8(a0)
move.w #$f,$dff096
rts
;------------------------------------------------------------------------------
;Function: PT_SetMasterVol(Left,Right)(D0,D1)
;Purpose: Sets left and right mastervolume.
;------------------------------------------------------------------------------
ifne PT_MasterVol
PT_SetMasterVol
move.w d0,PT_lmastervol
move.w d1,PT_rmastervol
lea.l $dff000,a5
moveq.l #0,d0
lea.l PT_chan1temp(pc),a0
move.b n_volume(a0),d0
mulu.w PT_lmastervol,d0
lsr.w #6,d0
move.b d0,$a8(a5)
moveq.l #0,d0
lea.l PT_chan2temp(pc),a0
move.b n_volume(a0),d0
mulu.w PT_rmastervol,d0
lsr.w #6,d0
move.b d0,$b8(a5)
moveq.l #0,d0
lea.l PT_chan3temp(pc),a0
move.b n_volume(a0),d0
mulu.w PT_rmastervol,d0
lsr.w #6,d0
move.b d0,$c8(a5)
moveq.l #0,d0
lea.l PT_chan4temp(pc),a0
move.b n_volume(a0),d0
mulu.w PT_lmastervol,d0
lsr.w #6,d0
move.b d0,$d8(a5)
moveq.l #0,d0
rts
endc
PT_calcvol macro
ifne PT_MasterVol
move.l a5,d5
subq.l #1,d5
and.w #32,d5
beq.s .left
.right mulu.w PT_rmastervol(pc),d0
bra.s .volend
.left mulu.w PT_lmastervol(pc),d0
.volend lsr.w #6,d0
endc
endm
;------------------------------------------------------------------------------
;Function: PT_Rewind()
;Purpose: Jumps one pattern backwards.
;------------------------------------------------------------------------------
ifne PT__WindFuncs
PT_Rewind bsr.w PT_KillSound
move.b PT_songpos,d0
tst.b d0
bne.s .not0
move.l PT_songdataptr,a0 ; get moduleptr.
move.b 950(a0),PT_songpos
sub.b #2,PT_songpos
ifne PT__OverStep
move.w #-1,PT_OverStep
endc
bra.s .ok
.not0 cmp.b #1,d0
bne.s .not1
move.l PT_songdataptr,a0 ; get moduleptr.
move.b 950(a0),PT_songpos
sub.b #1,PT_songpos
bra.s .ok
.not1
sub.b #2,PT_songpos
.ok move.w #63*16,PT_patternpos
move.b PT_speed(pc),PT_counter
moveq.l #0,d0
rts
;------------------------------------------------------------------------------
;Function: PT_Forward()
;Purpose: Jumps one pattern forwards.
;------------------------------------------------------------------------------
PT_Forward bsr.w PT_KillSound
move.w #63*16,PT_patternpos
move.b PT_speed(pc),PT_counter
moveq.l #0,d0
rts
endc
;------------------------------------------------------------------------------
;Function: PT_Music()
;Purpose: Updates the music. Call with steady intervals, preferably 50
; times a second.
;------------------------------------------------------------------------------
PT_Music addq.b #1,PT_counter
move.b PT_counter(pc),d0
move.b PT_speed(pc),d1
beq.w PT_return
cmp.b d1,d0
blo.s PT_nonewnote
clr.b PT_counter
tst.b PT_pattdeltime2
beq.w PT_getnewnote
bsr.s PT_nonewallchannels
bra.w PT_dskip
PT_nonewnote bsr.s PT_nonewallchannels
bra.w PT_nonewposyet
PT_nonewallchannels
lea.l $dff0a0,a5
lea.l PT_chan1temp(pc),a6
bsr.w PT_checkefx
lea.l $dff0b0,a5
lea.l PT_chan2temp(pc),a6
bsr.w PT_checkefx
lea.l $dff0c0,a5
lea.l PT_chan3temp(pc),a6
bsr.w PT_checkefx
lea.l $dff0d0,a5
lea.l PT_chan4temp(pc),a6
bra.w PT_checkefx
PT_getnewnote move.l PT_songdataptr(pc),a0
lea.l 12(a0),a3
lea.l 952(a0),a2 ;pattpo
lea.l 1084(a0),a0 ;patterndata
moveq.l #0,d0
moveq.l #0,d1
move.b PT_songpos(pc),d0
move.b (a2,d0.w),d1
lsl.l #8,d1
lsl.l #2,d1
add.w PT_patternpos(pc),d1
clr.w PT_dmacontemp
lea.l $dff0a0,a5
lea.l PT_chan1temp(pc),a6
bsr.s PT_playvoice
lea.l $dff0b0,a5
lea.l PT_chan2temp(pc),a6
bsr.s PT_playvoice
lea.l $dff0c0,a5
lea.l PT_chan3temp(pc),a6
bsr.s PT_playvoice
lea.l $dff0d0,a5
lea.l PT_chan4temp(pc),a6
bsr.s PT_playvoice
bra.w PT_setdma
PT_playvoice tst.w (a6)
bne.s PT_plvskip
bsr.w PT_pernop
PT_plvskip move.l (a0,d1.l),(a6)
addq.l #4,d1
moveq.l #0,d2
move.b n_cmd(a6),d2
and.b #$f0,d2
lsr.b #4,d2
move.b (a6),d0
and.b #$f0,d0
or.b d0,d2
tst.b d2
beq.w PT_setregs
moveq.l #0,d3
lea.l PT_samplestarts(pc),a1
move.w d2,d4
subq.l #1,d2
mulu.w #30,d4
ifeq PT__68020
lsl.l #2,d2
move.l (a1,d2.l),n_start(a6)
else
move.l (a1,d2.l*4),n_start(a6)
endc
move.w (a3,d4.l),n_length(a6)
move.w (a3,d4.l),n_reallength(a6)
move.b 2(a3,d4.l),n_finetune(a6)
move.b 3(a3,d4.l),n_volume(a6)
move.w 4(a3,d4.l),d3 ; get repeat
tst.w d3
beq.s PT_noloop
move.l n_start(a6),d2 ; get start
add.w d3,d3
add.l d3,d2 ; add repeat
move.l d2,n_loopstart(a6)
move.l d2,n_wavestart(a6)
move.w 4(a3,d4.l),d0 ; get repeat
add.w 6(a3,d4.l),d0 ; add replen
move.w d0,n_length(a6)
move.w 6(a3,d4.l),n_replen(a6) ; save replen
moveq.l #0,d0
move.b n_volume(a6),d0
PT_calcvol
move.w d0,8(a5) ; set volume
bra.s PT_setregs
PT_noloop move.l n_start(a6),d2
add.l d3,d2
move.l d2,n_loopstart(a6)
move.l d2,n_wavestart(a6)
move.w 6(a3,d4.l),n_replen(a6) ; save replen
moveq.l #0,d0
move.b n_volume(a6),d0
PT_calcvol
move.w d0,8(a5) ; set volume
PT_setregs move.w (a6),d0
and.w #$0fff,d0
beq.w PT_checkmoreefx ; if no note
move.w 2(a6),d0
and.w #$0ff0,d0
cmp.w #$0e50,d0
beq.s PT_dosetfinetune
move.b 2(a6),d0
and.b #$0f,d0
cmp.b #3,d0 ; toneportamento
beq.s PT_chktoneporta
cmp.b #5,d0
beq.s PT_chktoneporta
cmp.b #9,d0 ; sample offset
bne.s PT_setperiod
bsr.w PT_checkmoreefx
bra.s PT_setperiod
PT_dosetfinetune
bsr.w PT_setfinetune
bra.s PT_setperiod
PT_chktoneporta
bsr.w PT_settoneporta
bra.w PT_checkmoreefx
PT_setperiod move.w (a6),d7
and.w #$0fff,d7
lea.l PT_periodtable(pc),a4
moveq.l #0,d0
moveq.l #36,d2
PT_ftuloop cmp.w (a4,d0.w),d7
bhs.s PT_ftufound
addq.l #2,d0
dbra d2,PT_ftuloop
PT_ftufound moveq.l #0,d7
move.b n_finetune(a6),d7
mulu.w #36*2,d7
add.l d7,a4
move.w (a4,d0.w),n_period(a6)
move.w 2(a6),d0
and.w #$0ff0,d0
cmp.w #$0ed0,d0 ; notedelay
beq.w PT_checkmoreefx
move.w n_dmabit(a6),$dff096
btst #2,n_wavecontrol(a6)
bne.s PT_vibnoc
clr.b n_vibratopos(a6)
PT_vibnoc btst #6,n_wavecontrol(a6)
bne.s PT_trenoc
clr.b n_tremolopos(a6)
PT_trenoc move.l n_start(a6),(a5) ; set start
move.w n_length(a6),4(a5) ; set length
move.w n_period(a6),d0
move.w d0,6(a5) ; set period
move.w n_dmabit(a6),d0
or.w d0,PT_dmacontemp
bra.w PT_checkmoreefx
PT_setdma lea.l $bfe000,a5
PT_WaitDMA
PT_dummy001 move.w PT_dmacontemp(pc),d0
or.w #$8000,d0
move.w d0,$dff096
PT_WaitDMA
lea.l $dff000,a5
lea.l PT_chan4temp(pc),a6
move.l n_loopstart(a6),$d0(a5)
move.w n_replen(a6),$d4(a5)
lea.l PT_chan3temp(pc),a6
move.l n_loopstart(a6),$c0(a5)
move.w n_replen(a6),$c4(a5)
lea.l PT_chan2temp(pc),a6
move.l n_loopstart(a6),$b0(a5)
move.w n_replen(a6),$b4(a5)
lea.l PT_chan1temp(pc),a6
move.l n_loopstart(a6),$a0(a5)
move.w n_replen(a6),$a4(a5)
PT_dskip add.w #16,PT_patternpos
move.b PT_pattdeltime(pc),d0
beq.s PT_dskc
move.b d0,PT_pattdeltime2
clr.b PT_pattdeltime
PT_dskc tst.b PT_pattdeltime2
beq.s PT_dska
subq.b #1,PT_pattdeltime2
beq.s PT_dska
sub.w #16,PT_patternpos
PT_dska tst.b PT_pbreakflag
beq.s PT_nnpysk
sf PT_pbreakflag
moveq.l #0,d0
move.b PT_pbreakpos(pc),d0
clr.b PT_pbreakpos
lsl.w #4,d0
move.w d0,PT_patternpos
PT_nnpysk cmp.w #1024,PT_patternpos
blo.s PT_nonewposyet
PT_nextposition
moveq.l #0,d0
move.b PT_pbreakpos(pc),d0
move.w d0,PT_patternpos
clr.b PT_pbreakpos
clr.b PT_posjumpflag
addq.b #1,PT_songpos
and.b #$7f,PT_songpos
move.b PT_songpos(pc),d1
move.l PT_songdataptr(pc),a0
cmp.b 950(a0),d1
blo.s PT_nonewposyet
ifne PT__OverStep
move.w #1,PT_OverStep
endc
ifne PT__NTComp
move.b PT_looppos,PT_songpos
else
clr.b PT_songpos
endc
PT_nonewposyet
tst.b PT_posjumpflag
bne.s PT_nextposition
PT_return rts
PT_checkefx bsr.w PT_updatefunk
move.w n_cmd(a6),d0
and.w #$0fff,d0
beq.s PT_pernop
move.b n_cmd(a6),d0
and.b #$0f,d0
beq.s PT_arpeggio
cmp.b #1,d0
beq.w PT_portaup
cmp.b #2,d0
beq.w PT_portadown
cmp.b #3,d0
beq.w PT_toneportamento
cmp.b #4,d0
beq.w PT_vibrato
cmp.b #5,d0
beq.w PT_toneplusvolslide
cmp.b #6,d0
beq.w PT_vibratoplusvolslide
cmp.b #$e,d0
beq.w PT_e_commands
setback move.w n_period(a6),6(a5)
cmp.b #7,d0
beq.w PT_tremolo
cmp.b #$a,d0
beq.w PT_volumeslide
rts
PT_pernop move.w n_period(a6),6(a5)
rts
PT_arpeggio moveq.l #0,d0
move.b PT_counter(pc),d0
divs.w #3,d0
swap.w d0
tst.w d0
beq.s PT_arpeggio2
cmp.w #2,d0
beq.s PT_arpeggio1
moveq.l #0,d0
move.b n_cmdlo(a6),d0
lsr.b #4,d0
bra.s PT_arpeggio3
PT_arpeggio1 moveq.l #0,d0
move.b n_cmdlo(a6),d0
and.b #15,d0
bra.s PT_arpeggio3
PT_arpeggio2 move.w n_period(a6),d2
bra.s PT_arpeggio4
PT_arpeggio3 add.w d0,d0
moveq.l #0,d1
move.b n_finetune(a6),d1
mulu.w #36*2,d1
lea.l PT_periodtable(pc),a0
add.l d1,a0
moveq.l #0,d1
move.w n_period(a6),d1
moveq.l #36,d3
PT_arploop move.w (a0,d0.w),d2
cmp.w (a0),d1
bhs.s PT_arpeggio4
addq.l #2,a0
dbra d3,PT_arploop
rts
PT_arpeggio4 move.w d2,6(a5)
rts
PT_fineportaup tst.b PT_counter
bne.w PT_return
move.b #$0f,PT_lowmask
PT_portaup moveq.l #0,d0
move.b n_cmdlo(a6),d0
and.b PT_lowmask(pc),d0
move.b #$ff,PT_lowmask
sub.w d0,n_period(a6)
move.w n_period(a6),d0
and.w #$0fff,d0
cmp.w #113,d0
bpl.s PT_portauskip
and.w #$f000,n_period(a6)
or.w #113,n_period(a6)
PT_portauskip move.w n_period(a6),d0
and.w #$0fff,d0
move.w d0,6(a5)
rts
PT_fineportadown
tst.b PT_counter
bne.w PT_return
move.b #$0f,PT_lowmask
PT_portadown clr.w d0
move.b n_cmdlo(a6),d0
and.b PT_lowmask(pc),d0
move.b #$ff,PT_lowmask
add.w d0,n_period(a6)
move.w n_period(a6),d0
and.w #$0fff,d0
cmp.w #856,d0
bmi.s PT_portadskip
and.w #$f000,n_period(a6)
or.w #856,n_period(a6)
PT_portadskip move.w n_period(a6),d0
and.w #$0fff,d0
move.w d0,6(a5)
rts
PT_settoneporta
move.l a0,-(sp)
move.w (a6),d2
and.w #$0fff,d2
moveq.l #0,d0
move.b n_finetune(a6),d0
mulu.w #37*2,d0
lea.l PT_periodtable(pc),a0
add.l d0,a0
moveq.l #0,d0
PT_stploop cmp.w (a0,d0.w),d2
bhs.s PT_stpfound
addq.w #2,d0
cmp.w #37*2,d0
blo.s PT_stploop
moveq.l #35*2,d0
PT_stpfound move.b n_finetune(a6),d2
and.b #8,d2
beq.s PT_stpgoss
tst.w d0
beq.s PT_stpgoss
subq.w #2,d0
PT_stpgoss move.w (a0,d0.w),d2
move.l (sp)+,a0
move.w d2,n_wantedperiod(a6)
move.w n_period(a6),d0
clr.b n_toneportdirec(a6)
cmp.w d0,d2
beq.s PT_cleartoneporta
bge.w PT_return
move.b #1,n_toneportdirec(a6)
rts
PT_cleartoneporta
clr.w n_wantedperiod(a6)
rts
PT_toneportamento
move.b n_cmdlo(a6),d0
beq.s PT_toneportnochange
move.b d0,n_toneportspeed(a6)
clr.b n_cmdlo(a6)
PT_toneportnochange
tst.w n_wantedperiod(a6)
beq.w PT_return
moveq.l #0,d0
move.b n_toneportspeed(a6),d0
tst.b n_toneportdirec(a6)
bne.s PT_toneportaup
PT_toneportadown
add.w d0,n_period(a6)
move.w n_wantedperiod(a6),d0
cmp.w n_period(a6),d0
bgt.s PT_toneportasetper
move.w n_wantedperiod(a6),n_period(a6)
clr.w n_wantedperiod(a6)
bra.s PT_toneportasetper
PT_toneportaup
sub.w d0,n_period(a6)
move.w n_wantedperiod(a6),d0
cmp.w n_period(a6),d0
blt.s PT_toneportasetper
move.w n_wantedperiod(a6),n_period(a6)
clr.w n_wantedperiod(a6)
PT_toneportasetper
move.w n_period(a6),d2
move.b n_glissfunk(a6),d0
and.b #$0f,d0
beq.s PT_glissskip
moveq.l #0,d0
move.b n_finetune(a6),d0
mulu.w #36*2,d0
lea.l PT_periodtable(pc),a0
add.l d0,a0
moveq.l #0,d0
PT_glissloop cmp.w (a0,d0.w),d2
bhs.s PT_glissfound
addq.w #2,d0
cmp.w #36*2,d0
blo.s PT_glissloop
moveq.l #35*2,d0
PT_glissfound move.w (a0,d0.w),d2
PT_glissskip move.w d2,6(a5) ; set period
rts
PT_vibrato move.b n_cmdlo(a6),d0
beq.s PT_vibrato2
move.b n_vibratocmd(a6),d2
and.b #$0f,d0
beq.s PT_vibskip
and.b #$f0,d2
or.b d0,d2
PT_vibskip move.b n_cmdlo(a6),d0
and.b #$f0,d0
beq.s PT_vibskip2
and.b #$0f,d2
or.b d0,d2
PT_vibskip2 move.b d2,n_vibratocmd(a6)
PT_vibrato2 move.b n_vibratopos(a6),d0
lea.l PT_vibratotable(pc),a4
lsr.w #2,d0
and.w #$001f,d0
moveq.l #0,d2
move.b n_wavecontrol(a6),d2
and.b #$03,d2
beq.s PT_vib_sine
lsl.b #3,d0
cmp.b #1,d2
beq.s PT_vib_rampdown
move.b #255,d2
bra.s PT_vib_set
PT_vib_rampdown
tst.b n_vibratopos(a6)
bpl.s PT_vib_rampdown2
move.b #255,d2
sub.b d0,d2
bra.s PT_vib_set
PT_vib_rampdown2
move.b d0,d2
bra.s PT_vib_set
PT_vib_sine move.b (a4,d0.w),d2
PT_vib_set move.b n_vibratocmd(a6),d0
and.w #15,d0
mulu.w d0,d2
ifne PT__NTComp
move.l PT_vibshift,d0
lsr.w d0,d2
else
lsr.w #7,d2
endc
move.w n_period(a6),d0
tst.b n_vibratopos(a6)
bmi.s PT_vibratoneg
add.w d2,d0
bra.s PT_vibrato3
PT_vibratoneg sub.w d2,d0
PT_vibrato3 move.w d0,6(a5)
move.b n_vibratocmd(a6),d0
lsr.w #2,d0
and.w #$003c,d0
add.b d0,n_vibratopos(a6)
rts
PT_toneplusvolslide
bsr.w PT_toneportnochange
bra.w PT_volumeslide
PT_vibratoplusvolslide
bsr.s PT_vibrato2
bra.w PT_volumeslide
PT_tremolo move.b n_cmdlo(a6),d0
beq.s PT_tremolo2
move.b n_tremolocmd(a6),d2
and.b #$0f,d0
beq.s PT_treskip
and.b #$f0,d2
or.b d0,d2
PT_treskip move.b n_cmdlo(a6),d0
and.b #$f0,d0
beq.s PT_treskip2
and.b #$0f,d2
or.b d0,d2
PT_treskip2 move.b d2,n_tremolocmd(a6)
PT_tremolo2 move.b n_tremolopos(a6),d0
lea.l PT_vibratotable(pc),a4
lsr.w #2,d0
and.w #$001f,d0
moveq.l #0,d2
move.b n_wavecontrol(a6),d2
lsr.b #4,d2
and.b #$03,d2
beq.s PT_tre_sine
lsl.b #3,d0
cmp.b #1,d2
beq.s PT_tre_rampdown
move.b #255,d2
bra.s PT_tre_set
PT_tre_rampdown
tst.b n_vibratopos(a6)
bpl.s PT_tre_rampdown2
move.b #255,d2
sub.b d0,d2
bra.s PT_tre_set
PT_tre_rampdown2
move.b d0,d2
bra.s PT_tre_set
PT_tre_sine move.b (a4,d0.w),d2
PT_tre_set move.b n_tremolocmd(a6),d0
and.w #15,d0
mulu.w d0,d2
lsr.w #6,d2
moveq.l #0,d0
move.b n_volume(a6),d0
tst.b n_tremolopos(a6)
bmi.s PT_tremoloneg
add.w d2,d0
bra.s PT_tremolo3
PT_tremoloneg sub.w d2,d0
PT_tremolo3 bpl.s PT_tremoloskip
clr.w d0
PT_tremoloskip
cmp.w #$40,d0
bls.s PT_tremolook
move.w #$40,d0
PT_tremolook PT_calcvol
move.w d0,8(a5)
move.b n_tremolocmd(a6),d0
lsr.w #2,d0
and.w #$003c,d0
add.b d0,n_tremolopos(a6)
rts
PT_sampleoffset
moveq.l #0,d0
move.b n_cmdlo(a6),d0
beq.s PT_sononew
move.b d0,n_sampleoffset(a6)
PT_sononew move.b n_sampleoffset(a6),d0
lsl.w #7,d0
cmp.w n_length(a6),d0
bge.s PT_sofskip
sub.w d0,n_length(a6)
add.w d0,d0
add.l d0,n_start(a6)
rts
PT_sofskip move.w #$0001,n_length(a6)
rts
PT_volumeslide
moveq.l #0,d0
move.b n_cmdlo(a6),d0
lsr.b #4,d0
tst.b d0
beq.s PT_volslidedown
PT_volslideup add.b d0,n_volume(a6)
cmp.b #$40,n_volume(a6)
bmi.s PT_vsuskip
move.b #$40,n_volume(a6)
PT_vsuskip move.b n_volume(a6),d0
PT_calcvol
move.w d0,8(a5)
rts
PT_volslidedown
moveq.l #0,d0
move.b n_cmdlo(a6),d0
and.b #$0f,d0
PT_volslidedown2
sub.b d0,n_volume(a6)
bpl.s PT_vsdskip
clr.b n_volume(a6)
PT_vsdskip moveq.l #0,d0
move.b n_volume(a6),d0
PT_calcvol
move.w d0,8(a5)
rts
PT_positionjump
move.b n_cmdlo(a6),d0
subq.b #1,d0
move.b d0,PT_songpos
ifne PT__OverStep
move.w #1,PT_OverStep
endc
PT_pj2 clr.b PT_pbreakpos
st PT_posjumpflag
rts
PT_volumechange
moveq.l #0,d0
move.b n_cmdlo(a6),d0
cmp.b #$40,d0
bls.s PT_volumeok
moveq.l #$40,d0
PT_volumeok move.b d0,n_volume(a6)
PT_calcvol
move.w d0,8(a5)
rts
PT_patternbreak
moveq.l #0,d0
move.b n_cmdlo(a6),d0
move.l d0,d2
lsr.b #4,d0
mulu.w #10,d0
and.b #$0f,d2
add.b d2,d0
cmp.b #63,d0
bhi.s PT_pj2
move.b d0,PT_pbreakpos
st PT_posjumpflag
rts
PT_setspeed
moveq.l #0,d0
move.b 3(a6),d0
ifne PT__OverStep
bne.s .wasnotzero
move.w #1,PT_OverStep
.wasnotzero
endc
ifne PT__CIA
cmp.b #32,d0
blo.s .setspeed
.settempo bsr.w PT_SetIntRate
rts
endc
.setspeed clr.b PT_counter
move.b d0,PT_speed
rts
PT_checkmoreefx
bsr.w PT_updatefunk
move.b 2(a6),d0
and.b #$0f,d0
cmp.b #$9,d0
beq.w PT_sampleoffset
cmp.b #$b,d0
beq.w PT_positionjump
cmp.b #$d,d0
beq.w PT_patternbreak
cmp.b #$e,d0
beq.s PT_e_commands
cmp.b #$f,d0
beq.w PT_setspeed
cmp.b #$c,d0
beq.w PT_volumechange
bra.w PT_pernop
PT_e_commands move.b n_cmdlo(a6),d0
and.b #$f0,d0
lsr.b #4,d0
beq.s PT_filteronoff
cmp.b #1,d0
beq.w PT_fineportaup
cmp.b #2,d0
beq.w PT_fineportadown
cmp.b #3,d0
beq.s PT_setglisscontrol
cmp.b #4,d0
beq.w PT_setvibratocontrol
cmp.b #5,d0
beq.w PT_setfinetune
cmp.b #6,d0
beq.w PT_jumploop
cmp.b #7,d0
beq.w PT_settremolocontrol
cmp.b #9,d0
beq.w PT_retrignote
cmp.b #$a,d0
beq.w PT_volumefineup
cmp.b #$b,d0
beq.w PT_volumefinedown
cmp.b #$c,d0
beq.w PT_notecut
cmp.b #$d,d0
beq.w PT_notedelay
cmp.b #$e,d0
beq.w PT_patterndelay
cmp.b #$f,d0
beq.w PT_funkit
rts
PT_filteronoff
move.b n_cmdlo(a6),d0
and.b #1,d0
add.b d0,d0
and.b #$fd,$bfe001
or.b d0,$bfe001
rts
PT_setglisscontrol
move.b n_cmdlo(a6),d0
and.b #$0f,d0
and.b #$f0,n_glissfunk(a6)
or.b d0,n_glissfunk(a6)
rts
PT_setvibratocontrol
move.b n_cmdlo(a6),d0
and.b #$0f,d0
and.b #$f0,n_wavecontrol(a6)
or.b d0,n_wavecontrol(a6)
rts
PT_setfinetune
move.b n_cmdlo(a6),d0
and.b #$0f,d0
move.b d0,n_finetune(a6)
rts
PT_jumploop tst.b PT_counter
bne.w PT_return
move.b n_cmdlo(a6),d0
and.b #$0f,d0
beq.s PT_setloop
tst.b n_loopcount(a6)
beq.s PT_jumpcnt
subq.b #1,n_loopcount(a6)
beq.w PT_return
PT_jmploop move.b n_pattpos(a6),PT_pbreakpos
st PT_pbreakflag
rts
PT_jumpcnt move.b d0,n_loopcount(a6)
bra.s PT_jmploop
PT_setloop move.w PT_patternpos(pc),d0
lsr.w #4,d0
move.b d0,n_pattpos(a6)
rts
PT_settremolocontrol
move.b n_cmdlo(a6),d0
and.b #$0f,d0
lsl.b #4,d0
and.b #$0f,n_wavecontrol(a6)
or.b d0,n_wavecontrol(a6)
rts
PT_retrignote move.l d1,-(sp)
moveq.l #0,d0
move.b n_cmdlo(a6),d0
and.b #$0f,d0
beq.s PT_rtnend
moveq.l #0,d1
move.b PT_counter(pc),d1
bne.s PT_rtnskp
move.w (a6),d1
and.w #$0fff,d1
bne.s PT_rtnend
moveq.l #0,d1
move.b PT_counter(pc),d1
PT_rtnskp divu.w d0,d1
swap.w d1
tst.w d1
bne.s PT_rtnend
PT_doretrig move.w n_dmabit(a6),$dff096 ; channel dma off
move.l n_start(a6),(a5) ; set sampledata pointer
move.w n_length(a6),4(a5) ; set length
move.w #300,d0
PT_rtnloop1 dbra d0,PT_rtnloop1
move.w n_dmabit(a6),d0
bset #15,d0
move.w d0,$dff096
move.w #300,d0
PT_rtnloop2 dbra d0,PT_rtnloop2
move.l n_loopstart(a6),(a5)
move.l n_replen(a6),4(a5)
PT_rtnend move.l (sp)+,d1
rts
PT_volumefineup
tst.b PT_counter
bne.w PT_return
moveq.l #0,d0
move.b n_cmdlo(a6),d0
and.b #$f,d0
bra.w PT_volslideup
PT_volumefinedown
tst.b PT_counter
bne.w PT_return
moveq.l #0,d0
move.b n_cmdlo(a6),d0
and.b #$0f,d0
bra.w PT_volslidedown2
PT_notecut moveq.l #0,d0
move.b n_cmdlo(a6),d0
and.b #$0f,d0
cmp.b PT_counter(pc),d0
bne.w PT_return
clr.b n_volume(a6)
move.w #0,8(a5)
rts
PT_notedelay moveq.l #0,d0
move.b n_cmdlo(a6),d0
and.b #$0f,d0
cmp.b PT_counter(pc),d0
bne.w PT_return
move.w (a6),d0
beq.w PT_return
move.l d1,-(sp)
bra.w PT_doretrig
PT_patterndelay
tst.b PT_counter
bne.w PT_return
moveq.l #0,d0
move.b n_cmdlo(a6),d0
and.b #$0f,d0
tst.b PT_pattdeltime2
bne.w PT_return
addq.b #1,d0
move.b d0,PT_pattdeltime
rts
PT_funkit tst.b PT_counter
bne.w PT_return
move.b n_cmdlo(a6),d0
and.b #$0f,d0
lsl.b #4,d0
and.b #$0f,n_glissfunk(a6)
or.b d0,n_glissfunk(a6)
tst.b d0
beq.w PT_return
PT_updatefunk movem.l a0/d1,-(sp)
moveq.l #0,d0
move.b n_glissfunk(a6),d0
lsr.b #4,d0
beq.s PT_funkend
lea.l PT_funktable(pc),a0
move.b (a0,d0.w),d0
add.b d0,n_funkoffset(a6)
btst #7,n_funkoffset(a6)
beq.s PT_funkend
clr.b n_funkoffset(a6)
move.l n_loopstart(a6),d0
moveq.l #0,d1
move.w n_replen(a6),d1
add.l d1,d0
add.l d1,d0
move.l n_wavestart(a6),a0
addq.l #1,a0
cmp.l d0,a0
blo.s PT_funkok
move.l n_loopstart(a6),a0
PT_funkok move.l a0,n_wavestart(a6)
moveq.l #-1,d0
sub.b (a0),d0
move.b d0,(a0)
PT_funkend movem.l (sp)+,a0/d1
rts
PT_funktable dc.b 0,5,6,7,8,10,11,13,16,19,22,26,32,43,64,128
PT_vibratotable
dc.b 000,024,049,074,097,120,141,161
dc.b 180,197,212,224,235,244,250,253
dc.b 255,253,250,244,235,224,212,197
dc.b 180,161,141,120,097,074,049,024
PT_periodtable
; tuning 0, normal
dc.w 856,808,762,720,678,640,604,570,538,508,480,453
dc.w 428,404,381,360,339,320,302,285,269,254,240,226
dc.w 214,202,190,180,170,160,151,143,135,127,120,113
; tuning 1
dc.w 850,802,757,715,674,637,601,567,535,505,477,450
dc.w 425,401,379,357,337,318,300,284,268,253,239,225
dc.w 213,201,189,179,169,159,150,142,134,126,119,113
; tuning 2
dc.w 844,796,752,709,670,632,597,563,532,502,474,447
dc.w 422,398,376,355,335,316,298,282,266,251,237,224
dc.w 211,199,188,177,167,158,149,141,133,125,118,112
; tuning 3
dc.w 838,791,746,704,665,628,592,559,528,498,470,444
dc.w 419,395,373,352,332,314,296,280,264,249,235,222
dc.w 209,198,187,176,166,157,148,140,132,125,118,111
; tuning 4
dc.w 832,785,741,699,660,623,588,555,524,495,467,441
dc.w 416,392,370,350,330,312,294,278,262,247,233,220
dc.w 208,196,185,175,165,156,147,139,131,124,117,110
; tuning 5
dc.w 826,779,736,694,655,619,584,551,520,491,463,437
dc.w 413,390,368,347,328,309,292,276,260,245,232,219
dc.w 206,195,184,174,164,155,146,138,130,123,116,109
; tuning 6
dc.w 820,774,730,689,651,614,580,547,516,487,460,434
dc.w 410,387,365,345,325,307,290,274,258,244,230,217
dc.w 205,193,183,172,163,154,145,137,129,122,115,109
; tuning 7
dc.w 814,768,725,684,646,610,575,543,513,484,457,431
dc.w 407,384,363,342,323,305,288,272,256,242,228,216
dc.w 204,192,181,171,161,152,144,136,128,121,114,108
; tuning -8
dc.w 907,856,808,762,720,678,640,604,570,538,508,480
dc.w 453,428,404,381,360,339,320,302,285,269,254,240
dc.w 226,214,202,190,180,170,160,151,143,135,127,120
; tuning -7
dc.w 900,850,802,757,715,675,636,601,567,535,505,477
dc.w 450,425,401,379,357,337,318,300,284,268,253,238
dc.w 225,212,200,189,179,169,159,150,142,134,126,119
; tuning -6
dc.w 894,844,796,752,709,670,632,597,563,532,502,474
dc.w 447,422,398,376,355,335,316,298,282,266,251,237
dc.w 223,211,199,188,177,167,158,149,141,133,125,118
; tuning -5
dc.w 887,838,791,746,704,665,628,592,559,528,498,470
dc.w 444,419,395,373,352,332,314,296,280,264,249,235
dc.w 222,209,198,187,176,166,157,148,140,132,125,118
; tuning -4
dc.w 881,832,785,741,699,660,623,588,555,524,494,467
dc.w 441,416,392,370,350,330,312,294,278,262,247,233
dc.w 220,208,196,185,175,165,156,147,139,131,123,117
; tuning -3
dc.w 875,826,779,736,694,655,619,584,551,520,491,463
dc.w 437,413,390,368,347,328,309,292,276,260,245,232
dc.w 219,206,195,184,174,164,155,146,138,130,123,116
; tuning -2
dc.w 868,820,774,730,689,651,614,580,547,516,487,460
dc.w 434,410,387,365,345,325,307,290,274,258,244,230
dc.w 217,205,193,183,172,163,154,145,137,129,122,115
; tuning -1
dc.w 862,814,768,725,684,646,610,575,543,513,484,457
dc.w 431,407,384,363,342,323,305,288,272,256,242,228
dc.w 216,203,192,181,171,161,152,144,136,128,121,114
PT_chan1temp dc.l 0,0,0,0,0,$00010000,0, 0,0,0,0
PT_chan2temp dc.l 0,0,0,0,0,$00020000,0, 0,0,0,0
PT_chan3temp dc.l 0,0,0,0,0,$00040000,0, 0,0,0,0
PT_chan4temp dc.l 0,0,0,0,0,$00080000,0, 0,0,0,0
cnop 0,4
PT_samplestarts
dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
PT_songdataptr dc.l 0
PT_speed dc.b 0
PT_counter dc.b 0
PT_songpos dc.b 0
PT_pbreakpos dc.b 0
PT_posjumpflag dc.b 0
PT_pbreakflag dc.b 0
PT_lowmask dc.b 0
PT_pattdeltime dc.b 0
PT_pattdeltime2 dc.b 0
ifne PT__NTComp
PT_looppos dc.b 0
endc
even
PT_patternpos dc.w 0
PT_dmacontemp dc.w 0
ifne PT__OverStep
PT_OverStep dc.w 0
endc
ifne PT__NTComp
PT_vibshift dc.l 0
endc
PT_lmastervol dc.w 64
PT_rmastervol dc.w 64